// #include <iostream>
// #include <signal.h>
// #include <cstdlib>
// using namespace std;
// int cnt = 0;
// void handler(int signo)
// {
//     cout << "我是一个进程，刚刚获取了一个信号：" << signo << endl;
//     exit(1);
// }
// int main()
// {
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         signal(sig, handler);
//     }
//     // int b = 10;
//     // b /= 0;
 
//     // int *p = nullptr;
//     // *p = 100;
 
//     int a[10];
//     a[10000] = 100;
//     return 0;
// }
// #include<iostream>
// #include<signal.h>
// #include<unistd.h>
// using namespace std;
// int cnt = 0;
// int main()
// {
//     alarm(1);
//     //统计一下我们的进程在1s钟，cnt++多少次
//     while (1)
//     {
//         printf("hello : %d\n", cnt++);
//     }
//     return 0;
// }
// int main1()
// {
//     pid_t id = fork();
//     if (id == 0)
//     {
//         // 子进程
//         int *p = nullptr;
//         *p = 1000; // 野指针问题
//         exit(1);
//     }
//     // 父进程
//     int status = 0;
//     waitpid(id, &status, 0); 
//     cout<<status<<endl;
//     printf("exitcode: %d, signo: %d, core dump flag: %d\n", \
//     (status >> 8) & 0xFF, status & 0x7F, (status >> 7) & 0x1);
//     return 0;
// }
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;
int cnt = 0;
 
void handler(int signo)
{
    cout << "我是一个进程，刚刚获取了一个信号：" << signo << endl;
    // exit(1);
}
 
// 打印信号集
static void showPending(sigset_t *pendings)
{
    for (int sig = 1; sig <= 31; sig++)
    {
        // 检测特定的信号在不在此pending集合里
        if (sigismember(pendings, sig))
            cout << "1 ";
        else
            cout << "0 ";
    }
    cout << endl;
}
int main()
{
    cout << "pid: " << getpid() << endl;
    // 3、屏蔽所有的信号
    sigset_t set, oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    // sigfillset();//把信号全部置位
    for (int sig = 1; sig <= 31; sig++)
    {
        // 3.1、添加sig号信号到信号屏蔽字中
        sigaddset(&set, sig);
        // 2、signal
        signal(sig, handler);
    }
    // 3.2、设置用户及的信号屏蔽字到内核中，让当前进程屏蔽掉sig号信号
    sigprocmask(SIG_SETMASK, &set, &oset);
 
    // 1、不断的获取当前进程的pending信号集
    sigset_t pendings;
    while (true)
    {
        // 1.1、清空信号集
        sigemptyset(&pendings);
        // 1.2、获取当前进程（谁调用，谁获取）的pending信号集
        if (sigpending(&pendings) == 0)
        {
            // 1.3、打印一下当前进程的pending信号集
            showPending(&pendings);
        }
        sleep(1);
        cnt++;
        if (cnt == 20)
        {
            cout << "解除对2号信号的block..." << endl;
            sigset_t sigs;
            sigemptyset(&sigs);
            sigaddset(&sigs, 2);
            sigprocmask(SIG_UNBLOCK, &sigs, nullptr);
        }
    }
    return 0;
}